﻿using System;
using System.Windows.Shapes;
using BSU.GraduateWork.LinesIn3D;
using Brush = System.Windows.Media.Brush;

namespace BSU.GraduateWork.Visualizer
{
    public class VectorUI : Line2D
    {
        private double _x1;
        private double _y1;
        private double _z1;
        private double _x2;
        private double _y2;
        private double _z2;
        

        public VectorUI(double factor)
        {
            Factor = factor;

            HeadUI = new Ellipse { Width = 2, Height = 2 };
        }

        public double Factor { get; private set; }

        public bool IsZero { 
            get 
            { 
                return  BeginningX == EndX &&
                        BeginningY == EndY &&
                        BeginningZ == EndZ;
            }
        }

        public double BeginningX 
        {
            get { return _x1; }
            set
            {
                _x1 = value;
                Point1.X = value * Factor;
            }
        }
        public double BeginningY
        {
            get { return _y1; }
            set
            {
                _y1 = value;
                Point1.Y = value * Factor * -1;
            }
        }
        public double BeginningZ
        {
            get { return _z1; }
            set
            {
                _z1 = value;
                Point1.Z = value * Factor;
            }
        }
        public double EndX
        {
            get { return _x2; }
            set
            {
                _x2 = value;
                Point2.X = value * Factor;
            }
        }
        public double EndY
        {
            get { return _y2; }
            set
            {
                _y2 = value;
                Point2.Y = value * Factor * -1;
            }
        }
        public double EndZ
        {
            get { return _z2; }
            set
            {
                _z2 = value;
                Point2.Z = value * Factor;
            }
        }

        public double Length
        {
            get
            {
                return System.Math.Sqrt(
                    System.Math.Pow(EndX - BeginningX, 2) +
                    System.Math.Pow(EndY - BeginningY, 2) +
                    System.Math.Pow(EndZ - BeginningZ, 2)
                    );            
            }
        }

        public double AbsoluteLength
        {
            get
            {
                return System.Math.Sqrt(
                    System.Math.Pow(Point2.X - Point1.X, 2) +
                    System.Math.Pow(Point2.Y - Point1.Y, 2) +
                    System.Math.Pow(Point2.Z - Point1.Z, 2)
                    );
            }
        }

        public Brush Brush
        {
            get { return Stroke; }
            set
            {
                Stroke = value;
            }
        }


        public bool Equals(VectorUI vector)
        {
            return  BeginningX == vector.BeginningX && 
                    BeginningY == vector.BeginningY &&
                    BeginningZ == vector.BeginningZ &&
                    EndX == vector.EndX &&
                    EndY == vector.EndY &&
                    EndZ == vector.EndZ;
        }

        public override string ToString()
        {
            return SR.VectorToStringTemplate.Args(
                BeginningX, BeginningY, BeginningZ, 
                EndX, EndY, EndZ
                );
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (VectorUI)) return false;
            return Equals((VectorUI)obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int result = _x1.GetHashCode();
                result = (result*397) ^ _y1.GetHashCode();
                result = (result*397) ^ _z1.GetHashCode();
                result = (result*397) ^ _x2.GetHashCode();
                result = (result*397) ^ _y2.GetHashCode();
                result = (result*397) ^ _z2.GetHashCode();
                result = (result*397) ^ Factor.GetHashCode();
                return result;
            }
        }

        public bool HasValuesExceeding(double limit)
        {
            return !IsWithin(BeginningX, limit) ||
                   !IsWithin(BeginningY, limit) ||
                   !IsWithin(BeginningZ, limit) ||
                   !IsWithin(EndX, limit) ||
                   !IsWithin(EndY, limit) ||
                   !IsWithin(EndZ, limit);
        }
        private static bool IsWithin(double value, double limit)
        {
            return value <= limit && value >= (limit*-1);
        }
    }
}